/*
 * SHOPTNT 版权所有。
 * 未经许可，您不得使用此文件。
 * 官方地址：www.shoptnt.cn
 */
package cn.shoptnt.service.base.plugin.upload;

import cn.shoptnt.framework.exception.ServiceException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import cn.shoptnt.framework.util.StringUtil;
import cn.shoptnt.model.base.dto.FileDTO;
import cn.shoptnt.model.base.vo.ConfigItem;
import cn.shoptnt.model.base.vo.FileVO;
import cn.shoptnt.model.errorcode.SystemErrorCode;
import io.minio.*;
import org.springframework.stereotype.Component;

import java.util.*;


/**
 * @Program: GoodsQueryManagerImpl.java
 * @Author: 李正国
 * @Date: 2020-12-14 10:42
 * @Description: 本地文件
 */
@SuppressWarnings("unchecked")
@Component
public class MinIOPlugin implements Uploader {
    private final Logger logger = LoggerFactory.getLogger(getClass());
    // 单例模式的连接
    MinioClient minioClient;
    //连接地址属性
    String endpoint;

    /**
     * 获取配置参数
     */
    @Override
    public List<ConfigItem> definitionConfigItem() {
        List<ConfigItem> list = new ArrayList();

        ConfigItem endpoint = new ConfigItem();
        endpoint.setType("text");
        endpoint.setName("endpoint");
        endpoint.setText("minIO服务地址");

        ConfigItem serviceUrl = new ConfigItem();
        serviceUrl.setType("text");
        serviceUrl.setName("serviceUrl");
        serviceUrl.setText("图片展示地址");

        ConfigItem accessKey = new ConfigItem();
        accessKey.setType("text");
        accessKey.setName("accessKey");
        accessKey.setText("用户名");

        ConfigItem SecretKey = new ConfigItem();
        SecretKey.setType("text");
        SecretKey.setName("secretKey");
        SecretKey.setText("密钥");

        list.add(endpoint);
        list.add(serviceUrl);
        list.add(accessKey);
        list.add(SecretKey);

        return list;
    }


    /**
     * 获取连接
     */
    public MinioClient getClient(Map config, String scene) {
        String accessKeyId = StringUtil.toString(config.get("accessKey"));
        String accessKeySecret = StringUtil.toString(config.get("secretKey"));
        if (endpoint == null || !StringUtil.toString(config.get("endpoint")).equals(endpoint)) {
            endpoint = StringUtil.toString(config.get("endpoint"));
            minioClient = null;
        }

        //进行连接
        if (minioClient == null) {
            minioClient = MinioClient.builder().endpoint(endpoint)
                    .credentials(accessKeyId, accessKeySecret)
                    .build();
        }

        try {
            if (!minioClient.bucketExists(BucketExistsArgs.builder().bucket(scene).build())) {
                //创建桶
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(scene).build());
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        return minioClient;
    }

    @Override
    public FileVO upload(FileDTO input, String scene, Map config) {
        // 获取文件后缀
        String ext = input.getExt();
        //生成随机图片名
        String picName = UUID.randomUUID().toString().toUpperCase().replace("-", "") + "." + ext;
        String extnew;
        if ("mp4".equals(ext)) {
            extnew = "video/" + ext;
        } else {
            extnew = "image/" + ext;
        }
        try {
            //获取连接
            minioClient = this.getClient(config, scene);
            //文件上传
            minioClient.putObject(PutObjectArgs.builder().bucket(scene).object(picName).stream(
                    input.getStream(), -1, 10485760)
                    .contentType(extnew)
                    .build());
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new ServiceException(SystemErrorCode.E802.code(), "上传图片失败");
        }
        String serviceUrl = StringUtil.toString(config.get("serviceUrl"));
        FileVO file = new FileVO();
        file.setName(picName);
        file.setExt(ext);
        file.setUrl(serviceUrl + "/" + scene + "/" + picName);
        return file;
    }

    @Override
    public void deleteFile(String filePath, Map config) {

        String[] split = filePath.split("/");
        String bucketName = "";
        String objectName = "";
        for (int i = 0; i < split.length; i++) {
            if (i == 3) {
                bucketName = split[i];
            }
        }
        if (bucketName.length() > 3) {
            objectName = filePath.substring(filePath.indexOf(bucketName) + bucketName.length() + 1);
        } else {
            throw new ServiceException(SystemErrorCode.E803.code(), "删除失败，无法解析路径");
        }
        try {
            minioClient = this.getClient(config, bucketName);
            minioClient.removeObject(
                    RemoveObjectArgs.builder().bucket(bucketName).object(objectName).build());
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new ServiceException(SystemErrorCode.E903.code(), "删除图片失败");
        }

    }

    @Override
    public String getPluginId() {
        return "minIOPlugin";
    }

    @Override
    public String getThumbnailUrl(String url, Integer width, Integer height) {
        // 缩略图全路径
        String thumbnailPah = url + "_" + width + "x" + height;
        // 返回缩略图全路径
        return thumbnailPah;
    }

    @Override
    public Integer getIsOpen() {
        return 0;
    }

    @Override
    public String getPluginName() {
        return "MinIO存储";
    }
}
